package com.training.controller;

import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.training.dto.SupervisionDataDto;
import com.training.entity.Address;
import com.training.entity.ConfirmAqiData;
import com.training.entity.PublicSurveillanceData;
import com.training.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * @BelongsProject: environment-supervision
 * @BelongsPackage: com.training.controller
 * @Author: Tianyu Han
 * @CreateTime: 2024-05-27  09:54
 * @Description: 公众监督数据管理
 * @Version: 1.0
 */
@RestController
@RequestMapping("/supervisionData")
@Tag(name = "公众监督数据管理")
public class SupervisionDataController {

    @GetMapping()
    @Operation(summary = "监督数据综合查询")
    public SaResult getSupervisionData(@RequestParam(defaultValue = "1")Integer page,
                                       @RequestParam(defaultValue = "10")Integer pageSize,
                                       @RequestParam(defaultValue = "")String province,
                                       @RequestParam(defaultValue = "")String city,
                                       @RequestParam(defaultValue = "0")Integer estimatedLevel,
                                       LocalDateTime startTime, LocalDateTime endTime, String isAssigned) {
        // PublicSurveillanceData有address_id,没有province和city，比较日期的时候只保证年月日相同即可
        List<PublicSurveillanceData> data;
        boolean b = Objects.isNull(startTime) || Objects.isNull(endTime);
        if (estimatedLevel == 0){
            if (b) {
                data = Db.lambdaQuery(PublicSurveillanceData.class)
                        .eq(PublicSurveillanceData::getIsAssigned, isAssigned)
                        .orderByAsc(PublicSurveillanceData::getFeedbackTime)
                        .list();
            } else {
                data = Db.lambdaQuery(PublicSurveillanceData.class)
                        .between(PublicSurveillanceData::getFeedbackTime, startTime.toLocalDate(), endTime.toLocalDate())
                        .eq(PublicSurveillanceData::getIsAssigned, isAssigned)
                        .orderByAsc(PublicSurveillanceData::getFeedbackTime)
                        .list();
            }
        } else {
            if (b) {
                data = Db.lambdaQuery(PublicSurveillanceData.class)
                        .eq(PublicSurveillanceData::getEstimatedLevel, estimatedLevel)
                        .eq(PublicSurveillanceData::getIsAssigned, isAssigned)
                        .orderByAsc(PublicSurveillanceData::getFeedbackTime)
                        .list();

            } else {
                data = Db.lambdaQuery(PublicSurveillanceData.class)
                        .eq(PublicSurveillanceData::getEstimatedLevel, estimatedLevel)
                        .between(PublicSurveillanceData::getFeedbackTime, startTime.toLocalDate(), endTime.toLocalDate())
                        .orderByAsc(PublicSurveillanceData::getFeedbackTime)
                        .eq(PublicSurveillanceData::getIsAssigned, isAssigned)
                        .list();
            }
        }

        // 筛选出province和city相同的数据
        data = data.stream().filter(e -> {
            Address address = Db.lambdaQuery(Address.class).eq(Address::getId, e.getFeedbackAddressId())
                    .like(Address::getProvince, province).like(Address::getCity, city).one();
            return Objects.nonNull(address);
        }).toList();
        List<SupervisionDataDto> supervisionDataDtos = data.stream().map(e -> {
            Address oneAddress = Db.lambdaQuery(Address.class).eq(Address::getId, e.getFeedbackAddressId()).one();
            User supervisor = Db.getById(e.getSupervisorId(), User.class);
            return SupervisionDataDto.builder().id(e.getId()).supervisor(supervisor).address(oneAddress)
                    .estimatedLevel(e.getEstimatedLevel()).feedbackTime(e.getFeedbackTime())
                    .isAssigned(e.getIsAssigned()).build();
        }).toList();
        //手动分页，筛选supervisionDataDtos
        int start = (page - 1) * pageSize;
        int end = Math.min(page * pageSize, supervisionDataDtos.size());
        int total = supervisionDataDtos.size();
        supervisionDataDtos = supervisionDataDtos.subList(start, end);
        Map<String, Object> returnMap = Map.of("total", total, "data", supervisionDataDtos);
        return SaResult.data(returnMap);
    }

    @GetMapping("/{id}")
    @Operation(summary = "根据id获取监督数据")
    public SaResult getSupervisionDataById(@PathVariable String id) {
        PublicSurveillanceData data = Db.lambdaQuery(PublicSurveillanceData.class).eq(PublicSurveillanceData::getId, id).one();
        Address address = Db.lambdaQuery(Address.class).eq(Address::getId, data.getFeedbackAddressId()).one();
        User supervisor = Db.lambdaQuery(User.class).eq(User::getId, data.getSupervisorId()).one();
        SupervisionDataDto supervisionDataDto = SupervisionDataDto.builder().id(data.getId()).supervisor(supervisor)
                .description(data.getDescription())
                .address(address).estimatedLevel(data.getEstimatedLevel()).feedbackTime(data.getFeedbackTime())
                .isAssigned(data.getIsAssigned()).build();
        return SaResult.data(supervisionDataDto);
    }

    @PostMapping("/assign/{id}")
    @Operation(summary = "分配监督数据")
    public SaResult assignSupervisionData(@RequestBody SupervisionDataDto supervisionDataDto,  @PathVariable(name = "id") String inspectorId) {
        PublicSurveillanceData data = Db.lambdaQuery(PublicSurveillanceData.class)
                .eq(PublicSurveillanceData::getId, supervisionDataDto.getId()).one();
        if (Objects.isNull(data)) {
            return SaResult.error("数据不存在");
        } else if (data.getIsAssigned() == 1){
            return SaResult.error("已指派");
        }
        data.setIsAssigned(1);
        Db.lambdaUpdate(PublicSurveillanceData.class).update(data);
        ConfirmAqiData confirmAqiData = ConfirmAqiData.builder().inspectorId(inspectorId).isConfirmed(0)
                .addressId(data.getFeedbackAddressId()).surveillanceId(data.getId())
                .createTime(LocalDateTime.now()).updateTime(LocalDateTime.now())
                .aqi(data.getEstimatedLevel())
                .carbonMonoxideConcentration(0.0)
                .particulateMatter(0.0)
                .sulfurDioxideConcentration(0.0)
                .build();
        Db.save(confirmAqiData);
        return SaResult.ok("指派成功");
    }

    @GetMapping("/inspectors")
    public SaResult getInspectorsByAddress(String province, String city) {
        Address one = Db.lambdaQuery(Address.class).eq(Address::getProvince, province).eq(Address::getCity, city).one();
        if (Objects.isNull(one)) {
            return SaResult.error("该地没有网格员");
        }
        List<User> inspectors = Db.lambdaQuery(User.class)
                .select(User::getId, User::getRealName)
                .eq(User::getAddressId, one.getId())
                .list();
        return SaResult.data(inspectors);
    }
}
